#!/usr/bin/env python

from handlers import classes

class Runner:
	"""
	A wrapper to many types of applications (CGI, WSGI, XML, HTML) making them all WSGI
	Usage:
		import renyare.runner as runner
		wrapped_app = runner.Runner("my_app", "cgi", **some_args)
	In the example wrapped_app becomes a wsgi application and runs my_app.py(name is get from first parameter) module as cgi-application
	Also adds to environment variable 'renyare.applications' - an array of dictionaries with all runned applications
	and provides 'renyare.application' variable for every application with this application's info
	"""
	failed = False
	error = ""
	def __init__(self, app_module, app_type='wsgi',
					owner_document=None,
					app_args=None,
					main=False,
					orig_app=None):
		( self.app_type, self.app_module ) = ( app_type, app_module )
		self.app_is_main = main
		self.app_args = app_args
		self.app = orig_app
		self.owner_document = owner_document

	def __call__(self, environ, start_response):
		if(not self.owner_document):
			if(environ.has_key('renyare.page')):
				self.owner_document = environ['renyare.page']['document']
			else:
				import xml.dom.minidom as dom
				impl = dom.getDOMImplementation()
				self.owner_document = impl.createDocument(None, 'part', None)
		# Create handler instance
		handler_name = None
		if(classes.has_key(self.app_type)):
			handler_name = __import__('handlers', globals(), locals(), [classes[self.app_type][0]])
			handler_name = getattr(handler_name, classes[self.app_type][0])
			handler_class = getattr(handler_name, classes[self.app_type][1])
			self.app = handler_class(self.app_module, self.app_type, original_app=self.app, config=self.app_args)

		# Test if application has subclasses to import
		test = self.app_module.split(':')
		own_class = False
		if(len(test) == 1): # Application with default class name
			(filename, class_name) = ( self.app_module, self.app_module.split('.')[-1].title() )
		elif(len(test) == 2): # Application with action or alternate class name
			own_class = True
			(filename, class_name) = test
		else:
			raise renyare.error.Error("Wrong module name: " +self.app_module)

		# Create a node for application xml
		name = filename.split('.')
		app_info = {
			'name':name[-1],				# Application module name
			'full_name':filename,			# Full name with submodules
			'type':self.app_type,			# Application type
			'is_main':self.app_is_main, 		# Shows if application is main
			'document':None,			# A main document, where xml nodes are created
			'node':None,				# A node to append xml to
			'text':'',				# unparsed output
			'parameters':self.app_args,		# parameters from outside
			'styles':{'css':[], 'xsl':[]},		# stylesheets, if any
			}
		app_info['class_name'] = class_name
		app_node = None
		app_info['document'] = self.owner_document
		app_node = self.owner_document.createElementNS(None, 'part')
		app_info['node'] = app_node
		environ['renyare.application'] = app_info
		if(not environ.has_key('renyare.applications')): environ['renyare.applications'] = []
		environ['renyare.applications'].append(app_info)
		return self.app(environ, start_response)
